<template>
  <div class="app-container">
    <DragLayout>
      <template v-slot:left>
        <div class="left-container">
          <div
            class="left-container-header layui-btn-container border-style-bottom"
            style="display: flex"
          >
            <!-- 机构树 -->
            <div v-for="item in btnList.beforeList" :key="item.value">
              <el-button
                v-if="item.value === 'add'"
                :plain="true"
                :disabled="addBtn"
                @click="addOrg"
                >新增</el-button
              >
              <el-button
                v-if="item.value === 'delDept'"
                :plain="true"
                :disabled="!canDelete"
                @click="delDept"
                >删除</el-button
              >
            </div>
          </div>
        </div>

        <!-- S 文档目录 -->
        <CategoryTree
          :categoryName="categoryName"
          :cateOptions="cateOptions"
          nodeKey="codeRule"
          :currentNodeKey="currentNodeKey"
          @add="addCategoryFn"
          @edit="editCategory"
          @delete="_deleteCategoryById"
        ></CategoryTree>
        <!-- E 文档目录 -->
      </template>
      <template v-slot:right>
        <!-- E 查询条件  -->
        <CategoryForm
          ref="categoryRef"
          :form="form"
          v-model:queryParams="dataForm.queryParamsForm"
          :isAllCate="isAllCate"
          @handleQuery="handleQuery"
          @resetQuery="resetCate"
        ></CategoryForm>
        <!-- E 查询条件  -->
        <el-divider class="divider" />
        <el-row
          v-if="$permission('categoryFile:empower')"
          :gutter="10"
          class="mb10"
        >
          <el-col :span="1.5">
            <el-button
              type="primary"
              :disabled="isAllCate"
              plain
              size="small"
              @click="Authorization"
              >授权</el-button
            >
          </el-col>
        </el-row>
        <!-- S 权限组授权列表 -->
        <CategoryList
          :categoryList="cateList"
          :total="cateTotal"
          :showCheck="false"
          :queryParams="cateQueryParams"
          @delete="handleDelete"
        ></CategoryList>
        <!-- E 权限组授权列表 -->
      </template>
    </DragLayout>

    <!-- S 授权弹窗 -->
    <CategoryDialog
      v-if="categoryOpen"
      ref="cateDialog"
      :categoryList="categoryList"
      :open="categoryOpen"
      :total="total"
      :queryParams="queryParams"
      @getListDialog="getListDialog"
      @search="categorySearch"
      @submit="submit"
      @close="categoryClose"
      @handleSelectionChange="handleSelectionChange"
      @select="select"
    ></CategoryDialog>
    <!-- E 授权弹窗 -->
    <page-dialog
      v-if="modifyInfo.visible"
      :title="modifyInfo.title"
      v-model:visible="modifyInfo.visible"
      :width="modifyInfo.width"
      :bt-list="modifyInfo.btList"
    >
      <page-form
        class="paddingBox order-model-formBox flex_wrap_start_start"
        v-model:ref-obj="formOrgInfo.ref"
        :data="formOrgInfo.modifyData"
        :field-list="formOrgInfo.modifyFieldList"
        :rules="formOrgInfo.rules"
        :label-width="formOrgInfo.labelWidth"
      >
      </page-form>
    </page-dialog>
  </div>
</template>

<script setup name="categoryFile">
import {
  getCategoryListSelect,
  getCategoryDetail,
  addCategory,
  updateCategory,
  deleteCategoryById,
  filePortfolio,
} from '@/api/fileManager'
import { handleTree } from '@/utils/index'
import CategoryList from './categoryList.vue'
import CategoryDialog from './categoryDialog.vue'
import CategoryTree from './categoryTree.vue'
import CategoryForm from './categoryForm.vue'

const validateLetterNum = (rule, value, callback) => {
  if (value === '' || value === undefined) {
    callback(new Error('请输入编号规则'))
  } else {
    // 最多输入64个字符，并且以小写字母开头
    let reg = /^[a-z]{1}([A-Za-z0-9]{0,63})$/
    if (!reg.test(value)) {
      callback(
        new Error('编号规则只能由英文字母、数字组成，且必须以小写字母开头')
      )
      return
    }
    callback()
  }
}
const btnList = ref({
  beforeList: [],
  afterList: [],
})
const { proxy } = getCurrentInstance()
let categoryName = ref('')
let categoryOpen = ref(false)
let isAdd = ref(true) // 是否是新增
let currentCategory = ref({}) // 当前触发文档目录
const categoryList = ref([]) // 授权权限组弹窗列表
const categoryListTemp = ref([]) // 授权权限组弹窗列表缓存
let cateList = ref([]) // 授权权限组列表
let cateListTemp = ref([]) // 授权权限组列表缓存（弹窗取消重置列表数据）
const open = ref(false)
let total = ref(0) // 授权权限组弹窗类别总数
let cateTotal = ref(0) // 文档目录列表总数
const cateOptions = ref(undefined) // 文档目录
const identify = ref({
  // 启用停用标识 1-启用 0-停用
  start: '1',
  stop: '0',
})
// 分类form对象
const dataForm = ref({
  queryParamsForm: {
    status: identify.value.start,
    categoryName: undefined,
    codeRule: undefined,
  },
})
// toRefs批量引用，和ref的区别在于ref是单存的复制，和原数据无关，toRefs则是相当于引用，和原数据有关但不会更改UI界面
// const { queryParamsForm } = toRefs(dataForm)
// 分类列表对象
const cateData = reactive({
  cateQueryParams: {
    curPage: 1,
    pageSize: 10,
  },
})

const { cateQueryParams } = toRefs(cateData)
// 分类弹窗对象
const data = reactive({
  form: {},
  queryParams: {
    curPage: 1,
    pageSize: 10,
  },
})
const currentNodeKey = ref('')

const { queryParams, form } = toRefs(data)
const modifyInfo = ref({
  visible: false,
  title: '新增目录',
  width: '60%',
  btLoading: false,
  btList: [
    {
      label: '关闭',
      type: '',
      icon: '',
      event: closeModifyDept,
      show: true,
    },
    {
      label: '保存',
      type: 'primary',
      icon: '',
      event: updateOrg,
      saveLoading: false,
      show: true,
    },
  ],
})
const formOrgInfo = ref({
  ref: null,
  modifyData: {},
  labelWidth: '120px',
  modifyFieldList: [
    {
      label: '目录名称',
      value: 'categoryName',
      type: 'input',
    },
    {
      label: '目录编码',
      value: 'codeRule',
      type: 'input',
      maxlength: 50,
    },
    {
      label: '标识',
      value: 'status',
      type: 'radio-model',
      code: 'new_enabled_type',
    },
  ],
  rules: {
    categoryName: [
      { required: true, message: '请输入目录名称', trigger: 'blur' },
      { min: 0, max: 64, message: '长度不能大于64个字符', trigger: 'change' },
    ],
    codeRule: [
      {
        required: true,
        trigger: 'blur',
        validator: validateLetterNum,
      },
    ],
  },
})
const canDelete = computed(() => {
  return currentCategory.value.id && currentCategory.value.id !== -1
})
// 获取列表
function getConfigList() {
  let arr = [
    {
      label: '新增',
      value: 'add',
      show: proxy.$permission('categoryFile:add'),
    },
    {
      label: '删除',
      value: 'delDept',
      show: proxy.$permission('categoryFile:del'),
    },
  ]
  let list = arr.filter((item) => item.show)
  if (list.length > 0) {
    btnList.value.beforeList = list.slice(0, 2)
    btnList.value.afterList = list.slice(2, list.length)
  }
}
function addOrg() {
  isAdd.value = true
  modifyInfo.value.visible = true
}
function closeModifyDept() {
  modifyInfo.value.visible = false
}
// 更新或添加部门
function updateOrg() {
  formOrgInfo.value.ref.validate((valid) => {
    if (valid) {
      handelCategory()
      formOrgInfo.value.ref.resetFields()
    }
  })
}
function delDept() {
  _deleteCategoryById(currentCategory.value)
}
function categoryClose() {
  queryParams.value.curPage = 1
  selectCategory.value = []
  categoryOpen.value = false
  // cateList.value = proxy.$fn.deepClone(cateListTemp.value)
}

// 文档目录弹窗选择数据
let selectCategory = ref([])
function handleSelectionChange(data) {
  selectCategory.value = [...new Set(selectCategory.value.concat(data))]
}

// 移除选中的项
function select(selection, row) {
  let selected = selection.length && selection.indexOf(row) !== -1
  if (!selected) {
    selectCategory.value.forEach((element, index) => {
      if (element.id === row.id) {
        selectCategory.value.splice(index, 1)
      }
    })
  }
}

/** 获取类别下拉树结构 */
function _getCategoryList(currentKey) {
  getCategoryListSelect({
    includeStop: true,
  }).then((response) => {
    let res = handleTree(response.data, 'id')
    cateOptions.value = [
      { categoryName: '全部目录', id: -1, parentId: 0, children: res },
    ]
    if (currentKey) {
      currentNodeKey.value = ''
      proxy.$nextTick(() => {
        currentNodeKey.value = currentKey
      })
    }
  })
}

// 查询权限组数据
function categorySearch(val) {
  queryParams.value = Object.assign({ curPage: 1 }, val)
  _filePortfolio()
}

// 新增文档目录
function addCategoryFn(params) {
  isAdd.value = true
  resetCate()
  currentCategory.value = params
}

// 重置类别查询和列表
function resetCate() {
  isAdd.value = true
  dataForm.value.queryParamsForm = {
    status: identify.value.start,
    categoryName: undefined,
    codeRule: undefined,
  }
  cateList.value = []
  cateListTemp.value = []
  currentCategory.value = {}
  _getCategoryList()
}

// 编辑文档目录
const formVal = ref({
  status: identify.value.start,
  categoryName: undefined,
  codeRule: undefined,
})
const listTemp = ref([])
const isAllCate = ref(true)
// 点击分类，如果修改过类别基本信息，则提示是否需要保存
function editCategory(params) {
  isAdd.value = false
  currentCategory.value = params
  currentNodeKey.value = ''
  if (params.id === -1) {
    dataForm.value.queryParamsForm = params
    isAllCate.value = true
    cateList.value = []
    return
  } else {
    isAllCate.value = false
  }
  const hasPermi = proxy.$permission('fileManager:category:save')
  // 拥有保存权限才能对修改的数据进行保存
  if (hasPermi && checkEditOrNot()) {
    proxy
      .$confirm('是否对数据进行保存？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      .then(() => {
        const tempBool = proxy.$refs['categoryRef'].submitForm()
        if (!tempBool) {
          proxy.$message.warning('请按照提示正确输入数据')
          return
        }
        formVal.value = proxy.$fn.deepClone(params)
        handleQuery(params)
      })
      .catch(() => {
        // 取消保存数据
        setFormNotSave(params)
      })

    return
  }
  getCateList(params)
}

function setFormNotSave(params) {
  const formData = formVal.value
  dataForm.value.queryParamsForm = formData
  getCateList(params)
}

function getCateList(params) {
  isAdd.value = false
  formVal.value = proxy.$fn.deepClone(params)
  dataForm.value.queryParamsForm = params
  currentCategory.value = params
  _getCategoryDetail(params)
}

// 目录名称，编号规则，标识是否修改过
const isFormEdit = computed(() => {
  const params = dataForm.value.queryParamsForm
  const formData = formVal.value
  return (
    formData.id === params.id &&
    (formData.categoryName != params.categoryName ||
      formData.codeRule != params.codeRule ||
      formData.status != params.status)
  )
})

// 列表数据是否修改过
const isListEdit = computed(() => {
  // 判断是否是同一条数据
  const seemObj =
    formVal.value.id && formVal.value.id === dataForm.value.queryParamsForm.id
  const array = listTemp.value
  const cateVal = cateList.value
  let isEdie = false
  // 判断下载授权和受控申请是否修改
  if (array.length !== cateVal.length) {
    isEdie = true
    return seemObj && isEdie
  }
  for (let index = 0; index < array.length; index++) {
    if (
      array[index].allowDownloads !== cateVal[index].allowDownloads ||
      array[index].application !== cateVal[index].application
    ) {
      isEdie = true
    }
  }
  return seemObj && isEdie
})

// 检查类别信息是否被修改过
function checkEditOrNot() {
  if (isFormEdit.value || isListEdit.value) {
    return true
  }
  return false
}

// 根据id获取详情查询文档目录详情
function _getCategoryDetail(params) {
  getCategoryDetail(params.id).then((res) => {
    cateList.value = res.data.details
    cateListTemp.value = proxy.$fn.deepClone(res.data.details)
    listTemp.value = proxy.$fn.deepClone(res.data.details)
    cateTotal.value = res.total
    dataForm.value.queryParamsForm.categoryName = res.data.categoryName
    dataForm.value.queryParamsForm.codeRule = res.data.codeRule
    dataForm.value.queryParamsForm.status = res.data.status
    formVal.value = proxy.$fn.deepClone(dataForm.value.queryParamsForm)
  })
}

/** 保存按钮操作 */
async function handleQuery(params) {
  const tempBool = await proxy.$refs['categoryRef'].submitForm()
  if (!tempBool) {
    proxy.$message.warning('请按照提示正确输入数据')
    return
  }
  dataForm.value.queryParamsForm.curPage = 1
  handelCategory(params)
}

// 处理新增和编辑参数
function handelCategory(formParams) {
  if (currentCategory.value.id === -1) {
    addCategoryFn(currentCategory.value)
  }
  let currentCate = currentCategory.value
  if (!isAdd.value) {
    currentCate = dataForm.value.queryParamsForm
  }
  if (isAdd.value) {
    currentCate = formOrgInfo.value.modifyData
    modifyInfo.value.visible = false
  }
  let params = {
    categoryName: currentCate.categoryName,
    codeRule: currentCate.codeRule,
    details: cateList.value ? cateList.value : [],
    status: currentCate.status,
  }
  // 新增需要添加父级id
  if (isAdd.value) {
    params.parentId = currentCategory.value.id
    if (JSON.stringify(currentCategory.value) === '{}') {
      params.parentId = 0
    }
  }
  if (!isAdd.value) {
    // 编辑需要添加当前文档目录id和parentId
    params.id = currentCate.id
    params.parentId = currentCate.parentId
  }
  if (isAdd.value) {
    _addCategory(params)
  } else {
    _updateCategory(params, formParams)
  }
}

// 新增文档目录
function _addCategory(params) {
  addCategory(params).then((res) => {
    if (res.success) {
      resetCate()
      // _getCategoryList()
      showTip('新增成功')
    }
  })
}
// 编辑文档目录
function _updateCategory(params, formParams) {
  updateCategory(params)
    .then((res) => {
      if (res.success) {
        formVal.value = proxy.$fn.deepClone(params)
        listTemp.value = proxy.$fn.deepClone(params.details)
        _getCategoryList(params.codeRule)
        showTip('编辑成功')
      }
    })
    .catch(() => {
      formVal.value = proxy.$fn.deepClone(params)
      listTemp.value = proxy.$fn.deepClone(params.details)
      _getCategoryList()
    })
}

function showTip(msg) {
  proxy.$message.success({
    message: msg,
    showClose: true,
    duration: 3500,
  })
}

function _deleteCategoryById(params) {
  proxy
    .$confirm(
      '是否确认删除目录名称为"' + params.categoryName + '"的数据项?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
    .then(() => {
      currentCategory.value = params
      deleteCategoryById(params.id)
        .then((res) => {
          if (res.success) {
            _getCategoryList()
            showTip('删除成功')
            resetCate()
            isAllCate.value = true
          }
        })
        .catch((err) => {})
    })
    .catch(() => {})
}

/** 删除按钮操作 */
function handleDelete(scope) {
  const index = scope.$index
  cateList.value.splice(index, 1)
  cateListTemp.value.splice(index, 1)
}

/** 新增按钮操作 */
function Authorization() {
  categoryOpen.value = true
  queryParams.value.curPage = 1
  queryParams.value.pageSize = 10
  //proxy.$refs.cateList.setStyle()
}

function submit() {
  queryParams.value.curPage = 1
  // 设置已选权限组id，弹窗新加数据使用filePortfolioId，一起已有数据使用id
  selectCategory.value.forEach((element) => {
    element.filePortfolioId = element.filePortfolioId || element.id
  })
  // 授权需要将所有数据合并到列表
  cateList.value = [...new Set(cateList.value.concat(selectCategory.value))]
  cateListTemp.value = proxy.$fn.deepClone(cateList.value)
  selectCategory.value = []
  categoryOpen.value = false
}

/** 查询授权权限组列表 */
function _filePortfolio() {
  filePortfolio(queryParams.value).then((res) => {
    categoryList.value = res.data
    categoryListTemp.value = proxy.$fn.deepClone(categoryList.value)
    total.value = res.total
    synchronousList()
  })
}

// 打开弹窗设置选中数据与需要授权数据同步
function synchronousList() {
  delete queryParams.value.searchValue
  categoryList.value.forEach((element, index) => {
    cateList.value.forEach((item) => {
      // 设置禁用并且选中
      if (element.id === item.filePortfolioId) {
        item.isDisable = true
        item.selected = true
        item.id = item.filePortfolioId
        categoryList.value[index] = item
      }
    })

    // 设置分页切换后选中效果
    selectCategory.value.forEach((item) => {
      if (element.id === item.id) {
        item.selected = true
        categoryList.value[index] = item
      }
    })
  })
  // 保证数据可以正常选中
  setTimeout(() => {
    try {
      proxy.$refs.cateDialog.toogleRow()
    } catch (error) {}
  }, 0)
}

function getListDialog() {
  _filePortfolio()
}
// 重置已选数据状态
watch(categoryOpen, (val) => {
  categoryListTemp.value.forEach((element, index) => {
    delete categoryListTemp.value[index].isDisable
  })
  if (!val) {
    selectCategory.value = []
    categoryList.value = proxy.$fn.deepClone(categoryListTemp.value)
  }
  if (val) {
    _filePortfolio()
  }
})
onMounted(() => {
  getConfigList()
  _getCategoryList()
  _filePortfolio()
})
</script>

<style scoped>
.divider {
  margin: 12px 0;
}
</style>
